package com.ruiben.mall.controller;


import com.ruiben.mall.LoginRequired;
import com.ruiben.mall.impl.UserServiceImpl;
import com.ruiben.mall.pojo.User;
import com.ruiben.mall.pojo.UserAddress;
import com.ruiben.mall.utils.*;
import com.ruiben.mall.vo.UserVo;
import io.swagger.annotations.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import static com.ruiben.mall.config.Config.BASE_URL;
import static com.ruiben.mall.config.ErrorConfig.*;

@RestController
@Api(value = "用户相关业务的接口", tags = {"用户相关业务的controller"})
@RequestMapping("user")
public class UserController extends BaseController {

    @Value("${file_space}")
    private String fileSpace;


    @Autowired
    private UserServiceImpl userService;

//    public CommonJSONResult findPassword(){
//
//    }


    /**
     * 更改用户性别
     *
     * @param userId 用户id
     * @param sex    用户性别 0男1女
     * @return
     */
    @ApiOperation(value = "修改性别", notes = "通过id查找用户来修改性别")
    @PostMapping(value = "modifyUserSex")

    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true,
                    dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sex", value = "用户性别", required = true,
                    dataType = "String", paramType = "query")
    })
    @LoginRequired
    public CommonJSONResult updateUserSex(String userId, Boolean sex) {

        CommonJSONResult commonJSONResult = new CommonJSONResult();

        if (StringUtils.isBlank(userId)) {
            commonJSONResult.setStatus(ID_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(ID_NOT_EMPTY_MSG);
            return commonJSONResult;
        }


        if (sex == null) {
            commonJSONResult.setStatus(SEX_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(SEX_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        User user = new User();
        user.setId(userId);
        user.setSex(sex);

        boolean b = userService.updateUserInfo(user);
        if (b) {
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("修改失败");
        }
    }


    /**
     * 更改用户邮箱
     *
     * @param userId 用户id
     * @param email  用户邮箱
     * @return
     */
    @ApiOperation(value = "修改用户邮箱", notes = "通过id查找用户来修改用户邮箱")
    @PostMapping(value = "modifyUserEmail")

    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true,
                    dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "email", value = "用户email地址", required = true,
                    dataType = "String", paramType = "query")
    })
    @LoginRequired
    public CommonJSONResult updateUserEmail(String userId, String email) {
        CommonJSONResult commonJSONResult = new CommonJSONResult();
        if (StringUtils.isBlank(userId)) {
            commonJSONResult.setStatus(ID_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(ID_NOT_EMPTY_MSG);
            return commonJSONResult;
        }


        if (StringUtils.isBlank(email)) {
            commonJSONResult.setStatus(EMAIL_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(EMAIL_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        User user = new User();
        user.setId(userId);
        user.setEmail(email);

        boolean b = userService.updateUserInfo(user);
        if (b) {
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("修改失败");
        }
    }

    /**
     * 更改用户手机号
     *
     * @param userId 用户id
     * @param phone  用户手机号
     * @return
     */
    @ApiOperation(value = "修改手机号", notes = "通过id查找用户来修改用户手机号")
    @PostMapping(value = "modifyUserPhone")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true,
                    dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "phone", value = "用户手机号", required = true,
                    dataType = "String", paramType = "query")
    })
    @LoginRequired
    public CommonJSONResult updateUserPhone(String userId, String phone) {

        CommonJSONResult commonJSONResult = new CommonJSONResult();
        if (StringUtils.isBlank(userId)) {
            commonJSONResult.setStatus(ID_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(ID_NOT_EMPTY_MSG);
            return commonJSONResult;
        }


        if (StringUtils.isBlank(phone)) {
            commonJSONResult.setStatus(PHONE_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(PHONE_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        if (!PhontUtils.isPhone(phone)) {
            commonJSONResult.setStatus(PHONE_ERROR_CODE);
            commonJSONResult.setMsg(PHONE_ERROR_MSG);
            return commonJSONResult;
        }

        User user = new User();
        user.setId(userId);
        user.setPhone(phone);

        boolean b = userService.updateUserInfo(user);
        if (b) {
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("修改失败");
        }
    }


    /**
     * 更改用户密码
     *
     * @param userId    用户id
     * @param cPassword 用户原密码
     * @param nPassword 用户新密码
     * @param rPassword 用户确认密码
     * @return
     */
    @ApiOperation(value = "修改密码", notes = "通过id查找用户来修改用户密码")
    @PostMapping(value = "modifyUserPassword")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true,
                    dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "cPassword", value = "用户原密码", required = true,
                    dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "nPassword", value = "用户新密码", required = true,
                    dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "rPassword", value = "用户确认密码", required = true,
                    dataType = "String", paramType = "query")
    })
    public CommonJSONResult updateUserPassword(String userId, String cPassword, String nPassword, String rPassword) throws Exception {

        CommonJSONResult commonJSONResult = new CommonJSONResult();
        if (StringUtils.isBlank(userId)) {
            commonJSONResult.setStatus(ID_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(ID_NOT_EMPTY_MSG);
            return commonJSONResult;
        }


        if (StringUtils.isBlank(cPassword) || StringUtils.isBlank(nPassword) || StringUtils.isBlank(rPassword)) {
            commonJSONResult.setStatus(PASSWORD_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(PASSWORD_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        if (!nPassword.equals(rPassword)) {
            commonJSONResult.setStatus(PASSWORD_DIFFER_ERROR_CODE);
            commonJSONResult.setMsg(PASSWORD_DIFFER_ERROR_MSG);
            return commonJSONResult;
        }


        User userResult = userService.queryUserInfoById(userId);
        if (userResult.getPassword().equals(MD5Utils.getMD5Str(cPassword))) {

            User user = new User();
            user.setId(userId);
            user.setPassword(MD5Utils.getMD5Str(nPassword));

            boolean b = userService.updateUserInfo(user);
            if (b) {
                return CommonJSONResult.ok();
            } else {
                return CommonJSONResult.errorMsg("修改失败");
            }
        } else {
            commonJSONResult.setStatus(PASSWORD_ERROR_CODE);
            commonJSONResult.setMsg(PASSWORD_ERROR_MSG);
            return commonJSONResult;
        }

    }


    @ApiOperation(value = "用户上传头像", notes = "用户上传头像的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true,
                    dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/uploadFace", consumes = "multipart/*", headers = "content-type=multipart/form-data")
    @LoginRequired
    public CommonJSONResult uploadFace(String userId,
                                       @ApiParam(value = "用户头像文件", required = true) MultipartFile file) throws Exception {

        CommonJSONResult commonJSONResult = new CommonJSONResult();

        if (StringUtils.isBlank(userId)) {
            commonJSONResult.setStatus(ID_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(ID_NOT_EMPTY_MSG);
            return commonJSONResult;
        }


        // 保存到数据库中的相对路径
        String uploadPathDB = "/face" + "/" + userId;

        FileOutputStream fileOutputStream = null;
        InputStream inputStream = null;
        try {
            if (file != null) {

                String fileName = file.getOriginalFilename();
                if (StringUtils.isNotBlank(fileName)) {
                    // 文件上传的最终保存路径
                    String finalFacePath = fileSpace + uploadPathDB + "/" + fileName;
                    // 设置数据库保存的路径
                    uploadPathDB += ("/" + fileName);

                    File outFile = new File(finalFacePath);
                    if (outFile.getParentFile() != null || !outFile.getParentFile().isDirectory()) {
                        // 创建父文件夹
                        outFile.getParentFile().mkdirs();
                    }

                    fileOutputStream = new FileOutputStream(outFile);
                    inputStream = file.getInputStream();
                    IOUtils.copy(inputStream, fileOutputStream);
                }

            } else {
                return CommonJSONResult.errorMsg("上传出错...");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return CommonJSONResult.errorMsg("上传出错...");
        } finally {
            if (fileOutputStream != null) {
                fileOutputStream.flush();
                fileOutputStream.close();
            }
        }

        User user = new User();
        user.setId(userId);
        user.setHeadimg(uploadPathDB);
        userService.updateUserInfo(user);

        return CommonJSONResult.ok(BASE_URL + uploadPathDB);
    }


    @ApiOperation(value = "注册用户", notes = "用户注册")
    @PostMapping(value = "register")
    public CommonJSONResult register(String username, String password,String problem,String answer) throws Exception {

        CommonJSONResult commonJSONResult = new CommonJSONResult();

        if (StringUtils.isBlank(username)) {
            commonJSONResult.setStatus(USERNAME_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(USERNAME_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        if (StringUtils.isBlank(password)) {
            commonJSONResult.setStatus(PASSWORD_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(PASSWORD_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        if (StringUtils.isBlank(problem)){
            return CommonJSONResult.errorMsg("密保问题不能为空");
        }

        if (StringUtils.isBlank(answer)){
            return CommonJSONResult.errorMsg("密保答案不能为空");
        }

//        if (!password.equals(checkPassword)) {
//            commonJSONResult.setStatus(PASSWORD_DIFFER_ERROR_CODE);
//            commonJSONResult.setMsg(PASSWORD_DIFFER_ERROR_MSG);
//            return commonJSONResult;
//        }
//
//        if (StringUtils.isBlank(phone)) {
//            commonJSONResult.setStatus(PHONE_NOT_EMPTY_CODE);
//            commonJSONResult.setMsg(PHONE_NOT_EMPTY_MSG);
//            return commonJSONResult;
//        }
//
//
//        if (!PhontUtils.isPhone(phone)) {
//            commonJSONResult.setStatus(PHONE_ERROR_CODE);
//            commonJSONResult.setMsg(PHONE_ERROR_MSG);
//            return commonJSONResult;
//        }


        // 2. 判断用户名是否存在
        boolean usernameIsExist = userService.queryUsernameIsExist(username);
//        boolean phoneIsExist = userService.queryPhoneIsExist(phone);

        if (usernameIsExist) {
            commonJSONResult.setStatus(USERNAME_EXIST_CODE);
            commonJSONResult.setMsg(USERNAME_EXIST_ERROR_STR);
            return commonJSONResult;
        }

//        if (phoneIsExist) {
//            commonJSONResult.setStatus(PHONE_EXIST_CODE);
//            commonJSONResult.setMsg(PHONE_EXIST_ERROR_STR);
//            return commonJSONResult;
//        }


        // 3. 保存用户，注册信息


        User user = new User();
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setUserMoney(0L);
        user.setUsername(username);
        user.setProblem(problem);
        user.setAnswer(answer);
        user.setPassword(MD5Utils.getMD5Str(password));
//        user.setEmail(email);
//        user.setSex(sex);
        user.setIsdelete(false);
//        user.setBirthday(birthday);
//        user.setPhone(phone);

        //用户注册
        int resister = userService.registerUser(user);


        if (resister > 0) {
            String uniqueToken = TokenUtils.createJwtToken(user.getId());
            redis.set(USER_REDIS_SESSION + ":" + user.getId(), uniqueToken, 1000 * 60 * 30);
            UserVo userVo = new UserVo();

            BeanUtils.copyProperties(user, userVo);
            userVo.setUserToken(uniqueToken);
            commonJSONResult.setStatus(SUCCESS);
            commonJSONResult.setMsg(SUCCESS_STR);
            commonJSONResult.setData(userVo);
            return commonJSONResult;
        } else {
            commonJSONResult.setStatus(REGISTER_ERROR_CODE);
            commonJSONResult.setMsg(REGISTER_ERROR_STR);
            return commonJSONResult;
        }


    }



    @ApiOperation(value = "注册用户", notes = "用户注册")
    @PostMapping(value = "forgetPass")
    public CommonJSONResult forgetPass(String username, String password,String problem,String answer) throws Exception {

        CommonJSONResult commonJSONResult = new CommonJSONResult();

        if (StringUtils.isBlank(username)) {
            commonJSONResult.setStatus(USERNAME_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(USERNAME_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        if (StringUtils.isBlank(password)) {
            commonJSONResult.setStatus(PASSWORD_NOT_EMPTY_CODE);
            commonJSONResult.setMsg(PASSWORD_NOT_EMPTY_MSG);
            return commonJSONResult;
        }

        if (StringUtils.isBlank(problem)){
            return CommonJSONResult.errorMsg("密保问题不能为空");
        }

        if (StringUtils.isBlank(answer)){
            return CommonJSONResult.errorMsg("密保答案不能为空");
        }

        User user = new User();
        user.setUsername(username);
        user.setPassword(MD5Utils.getMD5Str(password));
        user.setProblem(problem);
        user.setAnswer(answer);

        boolean b = userService.forgetPass(user);
        if (b) {
            return CommonJSONResult.ok();
        }

        return CommonJSONResult.errorMsg("密码找回失败");
    }


    @ApiOperation(value = "用户登录", notes = "用户登录的接口")
    @PostMapping("/login")
    public CommonJSONResult login(String username,String password) throws Exception {

        CommonJSONResult commonJSONResult = new CommonJSONResult();


        // 1. 判断用户名和密码必须不为空
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            commonJSONResult.setStatus(LOGIN_USERNAME_PASSWORD_EMPTY_CODE);
            commonJSONResult.setMsg(LOGIN_USERNAME_PASSWORD_EMPTY_STR);
            return commonJSONResult;
        }


        if (PhontUtils.isPhone(username)) {//手机号登录

            // 2. 判断用户是否存在
            User userResult = userService.queryPhoneForLogin(username,
                    MD5Utils.getMD5Str(password));

            // 3. 返回
            return getCommonJSONResult(commonJSONResult, userResult);

        } else {
            // 2. 判断用户是否存在
            User userResult = userService.queryUserForLogin(username,
                    MD5Utils.getMD5Str(password));

            // 3. 返回
            return getCommonJSONResult(commonJSONResult, userResult);
        }


    }

    /**
     * 获取用户列表
     * @return
     */
    /**
     * 获取所有用户列表
     *
     * @param page
     * @return
     */
    @PostMapping("getUserList")
    public CommonJSONResult getUserList(Integer page) {

        if (page == null) {
            page = 1;
        }

        PagedResult userList = userService.getUserList(page, PAGE_SIZE);
        return CommonJSONResult.ok(userList);
    }


    /**
     * 获取用户信息
     *
     * @return
     */
    @PostMapping("getUserInfo")
    public CommonJSONResult getUserInfo(String id) {

        if (StringUtils.isBlank(id)) {
            return CommonJSONResult.build(ID_NOT_EMPTY_CODE, ID_NOT_EMPTY_MSG, null);
        }

        UserVo userInfo = userService.getUserInfo(id);
        userInfo.setHeadimg(BASE_URL + userInfo.getHeadimg());
        if (userInfo != null) {
            return CommonJSONResult.ok(userInfo);
        } else {
            return CommonJSONResult.errorMsg("没有该用户");
        }
    }

    /**
     * @return
     */
    @PostMapping("updateUserPass")
    @LoginRequired
    public CommonJSONResult updateUserInfo(User user, String checkPwd) throws Exception {

        if (StringUtils.isBlank(user.getId())) {
            return CommonJSONResult.build(ID_NOT_EMPTY_CODE, ID_NOT_EMPTY_MSG, null);
        }

        if (!StringUtils.isBlank(user.getPassword()) && !StringUtils.isBlank(checkPwd)) {
            if (!user.getPassword().equals(checkPwd)) {
                return CommonJSONResult.build(PASSWORD_DIFFER_ERROR_CODE, PASSWORD_DIFFER_ERROR_MSG, null);
            } else {
                user.setPassword(MD5Utils.getMD5Str(user.getPassword()));
            }
        } else {
            user.setPassword(null);
        }


        boolean b = userService.updateUserInfo(user);
        if (b) {
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("更新失败");
        }
    }

    private CommonJSONResult getCommonJSONResult(CommonJSONResult commonJSONResult, User userResult) {
        if (userResult != null) {
            userResult.setPassword("");
            UserVo userVO = setUserRedisSessionToken(userResult);
            return CommonJSONResult.ok(userVO);
        } else {
            commonJSONResult.setStatus(LOGIN_USERNAME_PASSWORD_ERROR_CODE);
            commonJSONResult.setMsg(LOGIN_USERNAME_PASSWORD_ERROR_STR);
            return commonJSONResult;
        }
    }

    private UserVo setUserRedisSessionToken(User userModel) {
        String uniqueToken = TokenUtils.createJwtToken(userModel.getId());
        redis.set(USER_REDIS_SESSION + ":" + userModel.getId(), uniqueToken, 1000 * 60 * 30);

        UserVo userVO = new UserVo();
        BeanUtils.copyProperties(userModel, userVO);
        userVO.setUserToken(uniqueToken);
        return userVO;
    }

    /**
     *
     */
    @PostMapping("addUserAddress")
    public CommonJSONResult addUserAddress(String userId,UserAddress address){

        if (StringUtils.isBlank(userId)){
            return CommonJSONResult.errorMsg("用户id不能为空");
        }

        if (StringUtils.isBlank(address.getPhone()) || address.getPhone().length()!=11){
            return CommonJSONResult.errorMsg("请填写正确的手机");
        }
        address.setUserid(userId);
        boolean b = userService.addUserAddress(address);
        if (b){
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("添加失败");
        }
    }

    @PostMapping("getUserAddressList")
    public CommonJSONResult getAddressListByUserId(String userId){

        if (StringUtils.isBlank(userId)){
            return CommonJSONResult.errorMsg("用户id不能为空");
        }

        List<UserAddress> userAddressList = userService.getUserAddressList(userId);
        if (userAddressList!=null&& userAddressList.size()>0){
            return CommonJSONResult.ok(userAddressList);
        } else {
            return CommonJSONResult.errorMsg("没有更多数据");
        }
    }

    @PostMapping("getDefaultAddress")
    public CommonJSONResult getDefaultAddress(String userId){

        if (StringUtils.isBlank(userId)){
            return CommonJSONResult.errorMsg("用户id不能为空");
        }

        UserAddress defaultAddress = userService.getDefaultAddress(userId);
        if (defaultAddress!=null){
            return CommonJSONResult.ok(defaultAddress);
        } else {
            return CommonJSONResult.errorMsg("没有更多数据");
        }
    }


    @PostMapping("updateUserAddress")
    public CommonJSONResult updateUserAddress(UserAddress address){
        if (StringUtils.isBlank(address.getId())){
            return CommonJSONResult.build(ID_NOT_EMPTY_CODE,ID_NOT_EMPTY_MSG,null);
        }

        boolean b = userService.updateUserAddress(address);
        if (b) {
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("更新失败");
        }
    }

    @PostMapping("setDefaultAddress")
    public CommonJSONResult setDefaultAddress(String userId,String addressId){
        if (StringUtils.isBlank(userId)){
            return CommonJSONResult.build(ID_NOT_EMPTY_CODE,ID_NOT_EMPTY_MSG,null);
        }

        if (StringUtils.isBlank(addressId)){
            return CommonJSONResult.errorMsg("地址id不能为空");
        }



        boolean b = userService.setDefaultAddress(userId,addressId);
        if (b) {
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("更新失败");
        }
    }

    /**
     * 根据id删除用户地址
     * @param id
     * @return
     */
    @PostMapping("delAddress")
    public CommonJSONResult delUserAddress(String id){
        if (StringUtils.isBlank(id)){
          return CommonJSONResult.build(ID_NOT_EMPTY_CODE,ID_NOT_EMPTY_MSG,null);
        }

        boolean b = userService.delUserAddress(id);
        if (b){
            return CommonJSONResult.ok();
        } else {
            return CommonJSONResult.errorMsg("删除失败");
        }
    }


    @PostMapping("/isLogin")
    public CommonJSONResult isLogin(String id) {
        String s = redis.get(USER_REDIS_SESSION + ":" + id);

        if (StringUtils.isBlank(s)) {
            return CommonJSONResult.errorTokenMsg("token过期，请重新登录");
        } else {
            return CommonJSONResult.ok(s);
        }

    }

    @PostMapping("logout")
    public CommonJSONResult logout(String userId){
        redis.del(USER_REDIS_SESSION + ":" +userId);
        return CommonJSONResult.ok();
    }

    @PostMapping("updateUserInfo")
    public CommonJSONResult updateUserInfo(User user){
        if (StringUtils.isBlank(user.getId())){
            return CommonJSONResult.errorMsg(ID_NOT_EMPTY_MSG);
        }

        boolean b = userService.updateUserInfo(user);
        if (b){
            return CommonJSONResult.ok();
        }

        return CommonJSONResult.errorMsg("更新失败");
    }


    /** 获取4位随机验证码
     * @return
             */
    public static String getValidationCode(){
        return String.valueOf((new Random().nextInt(8999) + 1000));
    }
}
